package com.lwc.backendsinglestructure.config;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.concurrent.TimeUnit;

/**
 * 缓存中的配置的序列化器与反序列化器的配置
 */
@Configuration
public class CacheConfig {

    /**
     * RedisTemplate 序列化器与反序列化器的配置
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
      RedisTemplate<String, Object> template = new RedisTemplate<>();
      template.setConnectionFactory(connectionFactory);
      template.setKeySerializer(new StringRedisSerializer());
      template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // 配置序列化器，如果不配置默认用的是jdk的序列化器，这样string结构存储对象的话，对象会以二进制形式存储在redis中，看起来不直观

      // 设置 Hash 结构的 field 和 value 序列化器
      template.setHashKeySerializer(new StringRedisSerializer()); // Hash key 通常用 String
      template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); // Hash value 用 JSON
      return template;
    }

    /**
     * Caffeine 缓存配置
     */
    @Bean
    public Cache<String, Object> caffeineCache() {
        Cache<String, Object> cache = Caffeine.newBuilder()
                // 初始容量
                .initialCapacity(100)
                // 最大缓存数量
                .maximumSize(500)
                // 缓存过期时间：写入缓存后，经过某个时间缓存失效
                .expireAfterWrite(10, TimeUnit.MINUTES)
                // 缓存失效监听器
                .removalListener((key, value, cause) -> System.out.println("key:" + key + " value:" + value + " cause:" + cause))
                // 开启统计功能
                .recordStats()
                .build();
        return cache;
    }
}
